package com.rentapark.app;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.StringWriter;
import java.util.List;
import java.util.Locale;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.MyLocationOverlay;
import com.google.android.maps.Overlay;
import com.google.android.maps.OverlayItem;

import data.DB;
import data.MyOverlays;

import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.drawable.Drawable;
import android.location.Address;
import android.location.Criteria;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.inputmethod.InputMethodManager;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.AdapterView.OnItemSelectedListener;

public class SearchScreen extends MapActivity implements LocationListener{
	LocationManager manager;
	List<Overlay> overlays;
	MapView view;
	MapController control;
	GeoPoint currentPoint;
	GeoPoint myLoc;
	String towers;
	int lat=0;
	int longi=0;
	MyLocationOverlay myLocation;
	private EditText addressToSearch;
	DB parking_db;
	boolean success=false;
	
	private final Handler handler = new Handler() {  
		public void handleMessage(Message msg) { 
			Log.d("parking spot Confirmation","confirmed");
			String bundleResult = msg.getData().getString("RESPONSE"); 
			
		} 
	}; 

	public void onCreate(Bundle savedInstanceState){   
		super.onCreate(savedInstanceState);
		Log.d("searchScreen","onCreate");
		setContentView(R.layout.search);
		//getting DB instance
		parking_db=DB.getInstance();
		//defining the map view
		view = (MapView) findViewById(R.id.themap);
		overlays= view.getOverlays();

		//map definitions
		view.setBuiltInZoomControls(true);
		view.setClickable(true);
		view.setLongClickable(true);
		control= view.getController();
		view.setBuiltInZoomControls(true);
		view.setClickable(true);
		view.setLongClickable(true);
		control= view.getController();
		//getting user's location
		manager= (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
		Criteria crit =new Criteria(); //get best deafult critiria (GPS/cellular/Wi-Fi)
		towers= manager.getBestProvider(crit, false); //best reception/power re/ things like that
		myLocation= new MyLocationOverlay(SearchScreen.this, view);	//enable my location
		myLocation.enableMyLocation();
		myLocation.runOnFirstFix(new Runnable() {
			public void run() {
				view.getController().animateTo(myLocation.getMyLocation());
			}
		}); 
		//adding overlay of user's location
		overlays.add(myLocation);	
		Location loc = manager.getLastKnownLocation(towers);	//get your location
		if(loc!=null)
		{
			lat=(int)(loc.getLatitude()*1E6);
			longi =(int)(loc.getLongitude()*1E6);
		}

		myLoc=new GeoPoint(lat, longi);
		currentPoint= myLoc;
		control.animateTo(myLoc);
		control.setZoom(16);
		view.invalidate();



		//buttons in the map
		//myLoc: button that takes you back to your present location 
		ImageButton currLoc=  (ImageButton) findViewById(R.id.myLoc);
		currLoc.setOnClickListener(new OnClickListener() {

			public void onClick(View v) {
				//get myLocation
				Location loc = manager.getLastKnownLocation(towers);
				if(loc!=null)
				{
					lat=(int)(loc.getLatitude()*1E6);
					longi =(int)(loc.getLongitude()*1E6);
				}
				myLoc=new GeoPoint(lat, longi);	
				currentPoint= myLoc;
				control.animateTo(myLoc);
				control.setZoom(16);
			}
		});
		//list: button that shows the user a list of the requests he has done. It starts "ListOfRequests" activity
		ImageButton listButton=(ImageButton) findViewById(R.id.request_list);
		listButton.setOnClickListener(new OnClickListener() {
			public void onClick(View v) {
				Intent intent = new Intent(SearchScreen.this, ListOfRequests.class);
				startActivity(intent);
			}
		});
		ImageButton parked=  (ImageButton) findViewById(R.id.goTarget);
		if(parking_db.dealClosed==false)
			parked.setVisibility(Button.GONE);
		else
		{
			parked.setOnClickListener(new OnClickListener() {

				public void onClick(View v) {
					if(parking_db.buyer==false)
					{
						Toast toast = Toast.makeText(SearchScreen.this, "You cannot report the parking confirmation\n the buying user does it..", Toast.LENGTH_LONG);
						toast.show();
						finish();
					}
					else
					{
						final Dialog dialog = new Dialog(SearchScreen.this);
					dialog.setContentView(R.layout.dialog);
					dialog.setTitle("Report parking");
					TextView text = (TextView) dialog.findViewById(R.id.text);
					text.setText("Do you want to report a successful parking deal?");
					Button dialogButton = (Button) dialog.findViewById(R.id.dialogButtonOK);
					// if button is clicked, close the custom dialog
					
					dialogButton.setText("Deal Succesfull");
					dialogButton.setOnClickListener(new OnClickListener() {
						@Override
						public void onClick(View v) {
							dialog.dismiss();
							success=true;
							performReport();
							
						}
					});
					Button dialogButton2 = (Button) dialog.findViewById(R.id.dialogButtonNo);
					// if button is clicked, close the custom dialog
					dialogButton2.setText("Deal Failed");
					dialogButton2.setOnClickListener(new OnClickListener() {
						@Override
						public void onClick(View v) {
							dialog.dismiss();
							success=false;
							performReport();
							
						}
					});
					dialog.show();
					}

				}
			});
		}
		
		


		addressToSearch= (EditText) findViewById(R.id.searchAddrET);
		ImageButton searchAd=  (ImageButton) findViewById(R.id.searchAdd);
		searchAd.setOnClickListener(new OnClickListener() {

			public void onClick(View v) {

				GeoPoint p= getForwardGeoCoder();
				currentPoint=p;
				control.animateTo(p);
				control.setZoom(15);
				Toast toast = Toast.makeText(SearchScreen.this, "Latitude is " + p.getLatitudeE6() + " " + "Longitude is " + p.getLongitudeE6(), Toast.LENGTH_LONG);
				toast.show();
			}
		});
		if(parking_db.dealClosed==false)
			drawPins();
		else
			drawTarget();



	}
	public void onStop()
	{
		super.onStop();
		Log.d("search screen","onStop");
		SharedPreferences ref = getSharedPreferences("com.ruthy.parkApp",MODE_PRIVATE);
		SharedPreferences.Editor ed = ref.edit();
		ed.putString("view", "enable");
		ed.commit();
	}
	protected String getReverseGeoCoder (GeoPoint point){
		Geocoder geoCoder= new Geocoder(getBaseContext(),Locale.getDefault());
		String 	display ="";
		try
		{
			List<Address> address =geoCoder.getFromLocation(point.getLatitudeE6()/1E6, point.getLongitudeE6()/1E6, 1);
			if(address.size()>0)
			{

				for(int i=0;i<address.get(0).getMaxAddressLineIndex();i++)
				{		
					display += address.get(0).getAddressLine(i)+ "\n";
				}
			}
		} catch (IOException ex) {
			ex.printStackTrace();
		}
		return display;
	}
	protected GeoPoint getForwardGeoCoder (){
		InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
		imm.hideSoftInputFromWindow(addressToSearch.getWindowToken(), 0);
		Geocoder geoCoder= new Geocoder(getBaseContext(),Locale.getDefault());
		GeoPoint pointToReturn =myLoc;
		try
		{
			List<Address> address= geoCoder.getFromLocationName(addressToSearch.getText().toString(), 8);
			if(address.size()>0)			
				pointToReturn =new GeoPoint((int)((address.get(0).getLatitude())*1E6), (int)((address.get(0).getLongitude())*1e6));

		} catch (IOException ex) {
			ex.printStackTrace();
		}	
		return pointToReturn;
	}
	public void drawTarget(){
		parking_db=DB.getInstance();
		for (int i=0; i<parking_db.dbList.list.size(); i++){
			if(parking_db.dbList.list.get(i).spotId==parking_db.spotRentId)
			{
				String snippet="";
				GeoPoint point=new GeoPoint((int)(parking_db.dbList.list.get(i).parkingCordinate.latitude*1e6),(int)(parking_db.dbList.list.get(i).parkingCordinate.longitude*1e6));
				OverlayItem flagItem= new OverlayItem(point, "Rented Parking spot", snippet);
				Drawable pin = this.getResources().getDrawable(R.drawable.flag);
				pin.setBounds(-pin.getIntrinsicWidth() / 2, -pin.getIntrinsicHeight(), pin.getIntrinsicWidth() / 2, 0);
				MyOverlays flags= new MyOverlays(pin, this);
				flags.addOverlay(flagItem);
				Log.d("parking status: ",Integer.toString(parking_db.dbList.list.get(i).status));
				view.getOverlays().add(flags);
			}
		}
	}

	public void drawPins(){

		parking_db=DB.getInstance();
		Log.d("searchScreen","drawPins");



		//		MyOverlays pinned=new MyOverlays(pin, this);

		for (int i=0; i<parking_db.dbList.list.size(); i++){
			GeoPoint point=new GeoPoint((int)(parking_db.dbList.list.get(i).parkingCordinate.latitude*1e6),(int)(parking_db.dbList.list.get(i).parkingCordinate.longitude*1e6));
			String dest=getReverseGeoCoder(point);
			String snippet= "Address: "+dest;
			parking_db.dbList.list.get(i).address=dest;
			snippet+="Available at: \n"+parking_db.dbList.list.get(i).timeToAvailable;
			snippet+="\n Price: "+Integer.toString(parking_db.dbList.list.get(i).prize);
			snippet+="\n Owner: "+parking_db.dbList.list.get(i).ownerName;
			snippet+="\n Owner's grade: "+Integer.toString(parking_db.dbList.list.get(i).ownerGrade);
			snippet+="\n Comments: "+parking_db.dbList.list.get(i).comment;
			OverlayItem flagItem= new OverlayItem(point, "Parking spot info", snippet);	
			//			SharedPreferences ref = getSharedPreferences("com.ruthy.parkApp",MODE_PRIVATE);
			Drawable pin;
			if(parking_db.dbList.list.get(i).status==0)
			{
				pin = this.getResources().getDrawable(R.drawable.mypin);
				pin.setBounds(-pin.getIntrinsicWidth() / 2, -pin.getIntrinsicHeight(), pin.getIntrinsicWidth() / 2, 0);
			}
			else
			{
				pin = this.getResources().getDrawable(R.drawable.red);
				pin.setBounds(-pin.getIntrinsicWidth() / 2, -pin.getIntrinsicHeight(), pin.getIntrinsicWidth() / 2, 0);

			}
			MyOverlays flags= new MyOverlays(pin, this);
			flags.addOverlay(flagItem);
			Log.d("parking status: ",Integer.toString(parking_db.dbList.list.get(i).status));
			view.getOverlays().add(flags);
		}
		
		view.invalidate();


	}



	protected boolean isRouteDisplayed() {
		// TODO Auto-generated method stub
		return false;
	}
	/////////////////////check!!!!!!!!!!!!

	public void onLocationChanged(Location location) {
		if(location!=null)
		{
			parking_db=DB.getInstance();
			Log.d("searchScreen","onlocChanged");
			double lat = location.getLatitude();
			double lng = location.getLongitude();
			GeoPoint myLoc =new GeoPoint((int)lat, (int)lng);
			myLocation.disableMyLocation();
			overlays.remove(myLocation);

			MyLocationOverlay myLocation2= new MyLocationOverlay(SearchScreen.this, view);	//enable my location
			myLocation2.enableMyLocation();
			overlays.add(myLocation2);	
			view.invalidate();

			parking_db.curLocLat=lat;
			parking_db.curLocLong=lng;

		}

	}



	public void onProviderDisabled(String provider) {
		// TODO Auto-generated method stub

	}


	public void onProviderEnabled(String provider) {
		// TODO Auto-generated method stub

	}


	public void onStatusChanged(String provider, int status, Bundle extras) {
		// TODO Auto-generated method stub

	}
	private void performReport() { 
		// create HTTP response handler to handle the HTTP response
		// the response data is extracted from the HTTP message and then it is wrapped in a message
		// which  is passed to the android handler for handling
		final ResponseHandler<String> responseHandler = new ResponseHandler<String>() {   
			public String handleResponse(HttpResponse response) {    
				//StatusLine status = response.getStatusLine();        
				HttpEntity entity = response.getEntity();          
				String result = null; 
				try { 
					result = inputStreamToString(entity.getContent());

					Message message = new Message();     
					Bundle bundle = new Bundle();         
					bundle.putString("RESPONSE", result); 
					message.setData(bundle); 
					handler.sendMessage(message);  
				} catch (IOException e) { 
					Log.e("Class6",  " ", e); 
				} 
				return result; 
			} 
		}; 


		// create and run the thread that perform the request and handle the response
		new Thread() {                          
			@Override 
			public void run() { 
				HttpClient httpclient = new DefaultHttpClient();
				Log.d("dbURL",parking_db.instanceDNS);
				String url="http://";
				url+=parking_db.instanceDNS;
				url+=":8080/ParkAndLetPark/ParkingConfirm";
				Log.d("url is",url);
				HttpPost httppost = new HttpPost(url);
				try {
					try{
						DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();

						DocumentBuilder docBuilder = builderFactory.newDocumentBuilder();
						//creating a new instance of a DOM to build a DOM tree.
						Document doc = docBuilder.newDocument();
						Element Response = doc.createElement("MSG_TYPE");
						Response.appendChild(doc.createTextNode("PARKING_CONFIRM"));
						doc.appendChild(Response);
						
						Element type = doc.createElement("CONFIRMATION");
						if(success==true)
							type.appendChild(doc.createTextNode("POSITIVE"));
						else
							type.appendChild(doc.createTextNode("NEGATIVE"));
						Response.appendChild(type);


						Element User = doc.createElement("user_id");
						User.appendChild(doc.createTextNode(Double.toString(parking_db.userID)));
						type.appendChild(User);
						
						Element owner = doc.createElement("owner_id");
						owner.appendChild(doc.createTextNode(Double.toString(parking_db.userDealId)));
						Response.appendChild(owner);

						Element ParkingSpot = doc.createElement("ParkingSpot");
						ParkingSpot.appendChild(doc.createTextNode(Integer.toString(parking_db.spotRentId)));
						owner.appendChild(ParkingSpot);

						

						TransformerFactory factory = TransformerFactory.newInstance();
						Transformer transformer = factory.newTransformer();

						transformer.setOutputProperty(OutputKeys.INDENT, "yes");

						StringWriter sw = new StringWriter();
						StreamResult result = new StreamResult(sw);
						DOMSource source = new DOMSource(doc);
						transformer.transform(source, result);
						String xmlString = sw.toString();
						Log.d("xmlString","^^^^^^^^^^^^^^^^^^^^"+xmlString);


						StringEntity se = new StringEntity(xmlString); //XML as a string
						se.setContentType("text/xml"); //declare it as XML
						httppost.setEntity(se);
						Log.d("work","post executed");


						String response = httpclient.execute(httppost,responseHandler);
						Log.d(""," "+response);

					}
					catch (ClientProtocolException e) {
						Log.e("LOGTAG", " " , e); 
					} catch (IOException e) {
						Log.e("LOGTAG", " " , e); 
					} catch (TransformerConfigurationException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}




				}
				catch(Exception e)
				{
					Log.e("LOGTAG", " " , e); 
				}
			}

		}.start(); 
	}
	

	public static String inputStreamToString(final InputStream stream) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(stream));
		StringBuilder sb = new StringBuilder();
		String line = null;
		while ((line = br.readLine()) != null) {
			sb.append(line + "\n");
		}
		br.close();
		return sb.toString();
	}


}
